"""
在抓取数据过程中，由于 服务器 设有 反爬虫机制，所以如果频繁用同一 IP 访问，会被服务器封禁。
所以为也更好地抓取服务器端的数据，需要使用到 代理IP。
代理IP 和 Cookie 的结合使用，可以让 handler 处理器更好抓取数据。

知识点：
- urllib.request import HTTPHandler,Request,HTTPCookieProcessor,build_opener,ProxyHandler
- urllib.parse import urlencode
- http.cookiejar import CookieJar
- import json

原理：
使用三种不同的 handler 对象作为参数创建 opener 对象。
然后使用 opener 对象 通过登录 API 接口 访问服务器，使 handler 对象携带 服务器返回的 Cookie
最后再使用 opener 对象直接访问 个人主页，此时因为 handler 携带 Cookie，且 代理IP 一样，所以无需登录，直接访问成功。
"""

from urllib.request import HTTPHandler, Request, HTTPCookieProcessor, ProxyHandler, build_opener
from urllib.parse import urlencode
from http.cookiejar import CookieJar
import json

# 首先确定服务器登录 API 接口
post_url = 'http://www.renren.com/ajaxLogin/login?1=1&uniqueTimestamp=20182122180'

# 接着分别创建三个 handler 对象，以作为参数创建 opener 对象访问服务器
# 这样就能使 opener 访问服务器具有 携带 cookie 和代理 IP 的功能
# 首先创建传输 HTTP 协议的 handler 对象
handler_1 = HTTPHandler()

# 接着创建 cookie 对象，以好创建 具有携带 cookie 的 handler 对象
cookie = CookieJar()

# 创建可以携带 cookie 的 handler 对象
handler_2 = HTTPCookieProcessor(cookie)

# 再创建具有 代理IP 功能的 handler
# 此时需要使用 代理IP，可以上网查找其他 IP 代理
# 注：这里的 proxies 可以写购买 代理IP 时所生成的 AIP链接
handler_3 = ProxyHandler(proxies={
	# 也可以写：'http': aip链接
	# 这里的 协议 模式应与 接口的 协议模式相同
	'http': 'http://117.93.193.105:8908'
})

# 根据三种 hanlder，创建 opener 对象
# 当然，如果只想要使用 代理IP，则只需要 ProxyHandler 创建的 handler 即可
opener = build_opener(handler_1, handler_2, handler_3)

# data
# 包含账号和密码
data = {
	'rkey': '1c7df63368df7ce73c234de26178ec11',
	'password': '19870115',
	'origURL': 'http://www.renren.com/home',
	'key_id': '1',
	'icode': '',
	'f': 'http://www.renren.com/224549540',
	'email': 'dqsygcz@126.com',
	'domain': 'renren.com',
	'captcha_type': 'web_login',
}

# 头部信息
headers = {
	'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.162 Safari/537.36',
	'Referer': 'http://www.renren.com/SysHome.do'
}

# 封装 post_url data 和 headers
# 因为是 POST 请求，data 需要先编码为 url 可识别类型，再编码为字节
request = Request(url=post_url, data=urlencode(data).encode('utf-8'), headers=headers)

# 通过拥有三种功能的 opener 访问服务器
# 返回的是携带 cookie 的响应数据
response = opener.open(request)

# print(response.read().decode('utf-8'))

# 读取返回的响应数据，并解码为字典形式
response_data = response.read().decode('utf-8')
print(response_data)
# 将读取的数据反序列化为 json 字符数据
json_data = json.loads(response_data)

# 判断数据中是否有 code 响应码
if json_data['code']:
	# 从数据中获取主页接口homeUrl
	req = json_data['homeUrl']
	# 通过这个接口，使用 opener 访问主页
	# 返回响应数据
	resp = opener.open(req)
	# 读取响应数据，并解码
	resp_data = resp.read().decode('utf-8')
	print(resp_data)
